﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;

namespace DotNetX
{
    /// <summary>
    /// This represents a parameter that the StringTokenizer will tokenize.
    /// </summary>
    public class StringTokenizationParameter
    {
        /// <summary>
        /// This is the key that indicates this parameter in the string to tokenize.
        /// </summary>
        public virtual string Key
        {
            get { return _key; }
            set { _key = value; }
        }
        private string _key = string.Empty;

        /// <summary>
        /// The value that should be put in place of the parameter.
        /// </summary>
        /// <remarks>
        /// This object will have .ToString() called to get the value to put in place of the parameter.
        /// </remarks>
        public virtual object Value
        {
            get { return _value; }
            set { _value = value; }
        }
        private object _value = null;

        /// <summary>
        /// The display name of this parameter
        /// </summary>
        public virtual string DisplayName
        {
            get
            {
                // do we have a display name?
                if (string.IsNullOrEmpty(this._displayName))
                    return this.Key;
                else
                    return this.DisplayName;
            }
            set { _displayName = value; }
        }
        private string _displayName = string.Empty;

        /// <summary>
        /// The modifier for this parameter
        /// </summary>
        public string Modifier
        {
            get { return _modifier; }
            set
            {
                // the value
                this._modifier = value.ToLower().Trim();

                // is the set modifier a name?
                if (ModifierNames.ContainsKey(this._modifier))
                {
                    // set the value
                    this._modifierValue = ModifierNames[this._modifier];
                }
                else
                {
                    // the modifier must not be a name of a modifier, so set both properties to be the modifier
                    this._modifierValue = this._modifier;
                }
            }
        }
        private string _modifier = string.Empty;

        /// <summary>
        /// The value of the set modifier.
        /// </summary>
        /// <remarks>
        /// This field is here because a modifier could be a set name, such as longdate. The Modifier property would contain the name of the modifier (longdate)
        /// and this field would contain the actual value (dd MMMMM yyyy)
        /// If the modifier is an acutal modifier, not a name, then both this property and Modifer property will have the same value.
        /// </remarks>
        public string ModifierValue
        {
            get
            {
                // return the value
                return this._modifierValue;
            }
        }
        protected string _modifierValue = string.Empty;

        /// <summary>
        /// Returns some preset modifiers for this parameter indicated by a name (date:longdate = date:ddddd MMMMM yyy)
        /// </summary>
        public virtual Dictionary<string, string> ModifierNames
        {
            get
            {
                // return the modifier names
                return _modifierNames;
            }
        }
        private static Dictionary<string, string> _modifierNames = new Dictionary<string, string>();

        public StringTokenizationParameter(string key, object value, string modifier)
        {
            if (key == null)
                throw new ArgumentNullException("'key' is null.");
            if (key.Length == 0)
                throw new ArgumentOutOfRangeException("'key' is zero-length.");
            if (value == null)
                throw new ArgumentNullException("'value' is null.");
            if (modifier == null)
                throw new ArgumentNullException("'modifier' is null.");

            // set the parameters
            this._key = key;
            this._value = value;
            this.Modifier = modifier;
        }

        public StringTokenizationParameter(string key, object value)
        {
            if (key == null)
                throw new ArgumentNullException("'key' is null.");
            if (key.Length == 0)
                throw new ArgumentOutOfRangeException("'key' is zero-length.");
            if (value == null)
                throw new ArgumentNullException("'value' is null.");

            // set the parameters
            this._key = key;
            this._value = value;
            this.Modifier = string.Empty;
        }

        /// <summary>
        /// This returns the value of this parameter
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            // return the value
            return this.Value.ToString();
        }

        /// <summary>
        /// This returns the value of this parameter by using the passed modifier
        /// </summary>
        /// <param name="modifier">The modifier to modify this parameter</param>
        /// <returns></returns>
        public string ToString(string modifier)
        {
            if (modifier == null)
                throw new ArgumentNullException("'modifier' is null.");

            // set the modifier
            this.Modifier = modifier;

            // return the value
            return this.ToString();
        }

        /// <summary>
        /// This returns sample versions of this parameter with all preset avaliable modifier names
        /// </summary>
        /// <returns>The sample parameters</returns>
        public virtual List<StringTokenizationParameter> GetSampleParametersWithModifierNames()
        {
            // return default
            return new List<StringTokenizationParameter>();
        }
    }
}
